package com.thinkit.utils.utils;


import com.thinkit.utils.iterator.BeanPropertyBox;
import com.thinkit.utils.iterator.BeanPropertyIterator;
import com.thinkit.utils.iterator.ThinkIterator;
import com.thinkit.utils.model.BaseDto;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

public class BeanEqUtil {

    public  static boolean equals(Object source, Object target){
        if(Checker.BeNull(source) || Checker.BeNull(target)){
            return false;
        }
        if(source.getClass().equals(target.getClass())){
            if(source instanceof Number){
                return ckSameNumber(source,target);
            }else if(source instanceof String){
                return source.toString().equals(target.toString());
            }else if(source instanceof Map){
                return ckSameMap(source,target);
            }else if(source instanceof BaseDto){
                return ckSameDto(source,target);
            }
        }
        return false;
    }



    private static boolean ckSameDto(Object source,Object target){
        ThinkIterator iterator = new BeanPropertyBox(source).iterator(BeanPropertyIterator.class);
        ThinkIterator iterator1 = new BeanPropertyBox(target).iterator(BeanPropertyIterator.class);
        Map sourceMap = new HashMap();
        Map targetMap = new HashMap();
        while (iterator.hasNext()){
            sourceMap.putAll((Map)iterator.next());
        }
        while (iterator1.hasNext()){
            targetMap.putAll((Map)iterator1.next());
        }
        return  ckSameMap(sourceMap,targetMap);
    }

    private static boolean ckSameMap(Object source,Object target){
         boolean same = true;
         Map sourceMap = (Map) source;
         Map targetMap = (Map) target;
         for(Object key:sourceMap.keySet()){
             if(!targetMap.containsKey(key)){
                 same =false;
                 break;
             }
             if(!sourceMap.get(key).equals(targetMap.get(key))){
                 same =false;
                 break;
             }
         }
         return same;
    }



    private static boolean ckSameNumber(Object source,Object target){
        if(source instanceof Long){
           return ((Long) source).longValue() ==  ((Long) target).longValue();
        }else if(source instanceof Integer){
            return ((Integer) source).intValue() ==  ((Integer) target).intValue();
        }else if(source instanceof BigDecimal){
            BigDecimal targetVal = (BigDecimal) target;
            return ((BigDecimal) source).compareTo(targetVal)==0;
        }else if(source instanceof Double){
            return ((Double) source).doubleValue() ==  ((Double) target).doubleValue();
        }else if(source instanceof Float){
            return ((Float) source).floatValue() ==  ((Float) target).floatValue();
        }
        return  false;
    }



}
